#include "board_data_proc.h"
#include <stdio.h>
#include <unistd.h>
#include <linux/can.h>
#include <string.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "msg_def.h"
#include "can_app.h"
#include <semaphore.h>
#include "common.h"
#include "../barcode/barcode.h"
#include "ack_msg.h"

extern void sendAckToGrpc(int statusCodeIn,int errorNumIn,int sid, int moduleId);

#ifdef _QPCR
const char * str_qpcr[QPCR_MAX_TYPE] = {
    "kpr",
    "kpf",
    "itr",
    "itf",
    "dtr",
    "dtf",
    "hight",
    "lowt",
    "lidt",
    "pt",
    "nt",
    "aht",
    "alt",
    "ct",
    "hkt",
    "lkt",
    "hst",
    "lst",
    "photo",
};
#endif

const int max_chan_num[MAX_BOARD_NUM] = 
{
    0,
    0,
    0,
    12,
    4,
    4,
    4,
    4,
};

void ele_ctl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut);
void io_expand_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut);
void cap_detect_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut);
void purification_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut);
void thermal_seal_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut);


int fd_data_temp;
//char strToWrite[1024];
int lenInStr;
int numData = 0;

func_board_data_proc const func_data_proc[MAX_BOARD_NUM] = {
    ele_ctl_data_proc,
    io_expand_data_proc,
    cap_detect_data_proc,
    purification_data_proc,
    thermal_seal_data_proc,
    qpcr_ctrl_data_proc,
    system_ctrl_data_proc,
    qpcr1_ctrl_data_proc,
    air_pressure_data_proc,
    scancode_data_proc,

};

void ele_ctl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("ele ctl board data proc\n");
    if(lenIn<3)
    {
        return;
    }
    unsigned char op_code = data[0];
    unsigned char chanNum = data[1];
    unsigned char type = data[2];
    
    recvDataEleCtl * pstCheckData = (recvDataEleCtl *)dataOut;

    switch(op_code)
    {
        case SUB_MOVE:
        {
            if(type==ELE_MOVE_FINISHED)
            {
                pstCheckData->sid = 80+chanNum;                
                pstCheckData->frameType = CHECK_MOVE_END;
                printf("ele with num[%d] move finished\n",chanNum);                
                sendAckToGrpc(0,0,80+chanNum,-1);
            }
            else if(type==ELE_RETBACK_FINISHED)
            {
                pstCheckData->sid = 80+chanNum;
                pstCheckData->frameType = CHECK_RET_BACK_END;
                printf("ele with num[%d] ret back finished\n",chanNum);
                sendAckToGrpc(0,0,80+chanNum,-1);
            }
        }
        break;
        default:
        break;
    }

}
unsigned char io_board_msg_src_dj[12];
unsigned char io_board_msg_src_drawer[MAX_I_DRAWER];
void io_expand_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("io expand board data proc,\n");
    unsigned char op_code = data[0];
    unsigned char lenData = lenIn-1;
    //can_frame * ptrDataOut = (can_frame *)dataOut;
    unsigned char chanNum = data[1];

    if(op_code==SUB_MOVE)
    {
        if(LIQUID_ACT_FINISHED == data[2])
        {
            //printf("chanNum_1:%d,chanNum&0xf0:%02x\n",chanNum,chanNum&0xf0);
            unsigned char chanNumTmp = chanNum;
            if(chanNum&0xf0)
            {
                chanNum = (chanNum&0x0f) + 6;
            }

            if(chanNum>=12)
            {
                printf("chanNum_2:%d\n",chanNum);
                return;
            }
            //printf("chanNum:%d,msgSrc:%d\n",chanNum, io_board_msg_src_dj[chanNum]);
            if(io_board_msg_src_dj[chanNum] == MSG_FROM_GRPC)
            {
                sendAckToGrpc(0,0,84+chanNum,-1);
            }
            else if(io_board_msg_src_dj[chanNum] == MSG_FROM_LUA)
            {
                sendAckToLua(SUBBOARD_BASE+(IO_EXPAND_BOARD<<5)+chanNumTmp,CHECK_MOVE_END);
            }
        }

    }
    else if(SUB_SIGNAL == op_code)
    {
        if(FLOATER_SIG == data[2])
        {
            recvDataEleCtl stAckData;// = (recvDataEleCtl *)ackDataIn; 
            memset(&stAckData,0,sizeof(recvDataEleCtl));

            stAckData.sid = SUBBOARD_BASE+(IO_EXPAND_BOARD<<5)+chanNum;
            stAckData.frameType = CHECK_MOVE_END;
            stAckData.un_param.param_i = data[3];
            sendAckToLua(&stAckData);
        }
        else if(SCANCODE_DRAWER_LOCK == data[2])
        {
            unsigned char frameType = ((data[1]&0x00c0) >> 6);

            unsigned char dataLen = data[2];

            if(g_barcode_handle)
            {
                g_barcode_handle->scan_end(chanNum);
            }
        }
    }
    else if(SUB_ACK == op_code)
    {
        if(DRAWER_LOCK == data[2])
        {
            if(chanNum>=MAX_I_DRAWER)
            {
                return;
            }

            if(io_board_msg_src_drawer[chanNum] == MSG_FROM_GRPC)
            {
                sendAckToGrpc(0,0,98+chanNum,-1);
            }
            else if(io_board_msg_src_drawer[chanNum] == MSG_FROM_LUA)
            {
                sendAckToLua(SUBBOARD_BASE+(IO_EXPAND_BOARD<<5)+chanNum+MAX_NUM_PV+1,CHECK_MOVE_END);
            }
        }
    }


}


extern sem_t sem_liquid_detect;
int flagLiquidCheck = 0;
void cap_detect_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("cap_detect board data proc\n");//the board id has been jumpped here
    unsigned char op_code = data[0];
    unsigned char lenData = lenIn-1;
    can_frame * ptrDataOut = (can_frame *)dataOut;
    unsigned char chanNum = data[1];
    if(op_code == SUB_ECHO)
    {
        for(int i=0;i<lenData;i++)
        {
            printf("%02x,",data[i+1]);
        }
        printf("\n");

        if(data[1]==1)
        {
            if(ptrDataOut!=NULL)
            {
                ptrDataOut->can_dlc = 2;
                ptrDataOut->data[0] = CENTRE_ECHO;
                ptrDataOut->data[1] = 0x02;
            }
            
        }
    }
    else if(SUB_CAPACITY == op_code)
    {
        if(lenIn>=4 && lenIn<=7)
        {
            unsigned short capValue = data[2] + (data[3]<<8);
            char dataStr[16];
            memset(dataStr,0,16);
            sprintf(dataStr,"%d\r\n",capValue);
            if(g_fileCapData)
            {
                g_fileCapData->addToDataBuff(dataStr,strlen(dataStr),chanNum);
            }
            printf("capacity received,chan:%d,value:%d\n",chanNum,capValue);
        }
        
        if(lenIn==7)
        {
            unsigned short capValue = data[5] + (data[6]<<8);
            char dataStr[16];
            memset(dataStr,0,16);
            sprintf(dataStr,"%d\r\n",capValue);
            if(g_fileCapData)
            {
                g_fileCapData->addToDataBuff(dataStr,strlen(dataStr),chanNum+1);
            }
        }
    }
    else if(SUB_INTERRUPT == op_code && chanNum == 0x0f)
    {
        unsigned short capStatus = data[2];
        capStatus += (data[3] << 8);

        printf("cap status: %04x\n",capStatus);
        //send the semphore here
        // if(flagLiquidCheck==0)
        // {
        //     flagLiquidCheck = 1;
        //     sem_post(&sem_liquid_detect);            
        // }
        
    }
    else if(SUB_NOTIFY == op_code && chanNum == 0x0f)
    {

        if(CAP_PROBE_LIQUID == data[2])
        {
            printf("all chan detected liquid\n");
            //send the semphore here
            if(flagLiquidCheck==0)
            {
                flagLiquidCheck = 1;
                sem_post(&sem_liquid_detect);            
            }

        }       
        
    }
}

float const temp2res[] =
{
	96.09,  96.48,  96.87,  97.26,  97.65,  98.04,  98.44,  98.83,  99.22,  99.61,	// -10 ~ -1
	100.00, 100.39, 100.78, 101.17, 101.56, 101.95, 102.34, 102.73, 103.12, 103.51,	// 0~9
	103.90, 104.29, 104.68, 105.07, 105.46, 105.85, 106.24, 106.63, 107.02, 107.40,	// 10~19
	107.79, 108.18, 108.57, 108.96, 109.35, 109.73, 110.12, 110.51, 110.90, 111.29,	// 20~29
	111.67, 112.06, 112.45, 112.83, 113.22, 113.61, 114.00, 114.38, 114.77, 115.15,	// 30~39
	115.54, 115.93, 116.31, 116.70, 117.08, 117.47, 117.86, 118.24, 118.63, 119.01,	// 40~49
	119.40, 119.78, 120.17, 120.55, 120.94, 121.32, 121.71, 122.09, 122.47, 122.86,	// 50~59
	123.24, 123.63, 124.01, 124.39, 124.78, 125.16, 125.54, 125.93, 126.31, 126.69,	// 60~69
	127.08, 127.46, 127.84, 128.22, 128.61, 128.99, 129.37, 129.75, 130.13, 130.52,	// 70~79
	130.90, 131.28, 131.66, 132.04, 132.42, 132.80, 133.18, 133.57, 133.95, 134.33,	// 80~89
	134.71, 135.09, 135.47, 135.85, 136.23, 136.61, 136.99, 137.37, 137.75, 138.13,	// 90~99
	138.51, 138.88, 139.26, 139.64, 140.02, 140.40, 140.78, 141.16, 141.54, 145.69, // 100~109
	142.29,	142.67,	143.05,	143.43,	143.80,	144.18,	144.56,	144.94,	145.31,	145.69,	// 110~119
	146.07,	146.44,	146.82,	147.20,	147.57, 147.95, 148.33, 148.70, 149.08, 149.49,	// 120~129
	149.83, 150.21, 150.58, 150.96, 151.33, 151.71, 152.08, 152.46, 152.83, 153.21, // 130~139
	153.58, 153.96, 154,33, 154.71, 155.08, 155.46, 155.83, 156.20, 156.58, 156.95, // 140~149
	157.33, 157.70, 158.07, 158.45, 158.82, 159.19, 159.56, 159.94, 160.31, 160.68, // 150~159
	161.05, 161.43, 161.80, 162.17, 162.54, 162.91, 163.29, 163.66, 164.03, 164.40, // 160~169
	164.77, 165.14, 165.51, 165.89, 166.26, 166.63, 167.00, 167.37, 167.74, 168.11,	// 170~179
	168.48, 168.85, 169.22, 169.59, 169.96, 170.33, 170.70, 171.07, 171.43, 171.80,	// 180~189
	172.17, 172.54, 172.91, 173.28, 173.65, 174.02, 174.38, 174.75, 175.12, 175.49	// 190~199
};

#define Au		10	// 放大倍数

float convertTemperature(unsigned short adc)
{
	float res;	// 电阻值
	unsigned char i;	// 循环比较次数，也就是温度，步长1°C
	
#ifdef _GP_1	
	res = adc * 4.09600 / 65535.00000 / Au / 0.00124;
#else
    res = adc * 4.096 / 65535.00000 / Au / 0.001;
#endif
//	switch(position)
//	{
//#if 1
//		case 1:	res -= 0.988;break;
//		case 2: res -= 2.07;break;
//		case 3: res -= 1.515;break;
//		case 4: res -= 1.66;break;
//#else
//		case 1:	res -= 0.947;break;
//		case 2: res -= 2.07;break;
//		case 3: res -= 1.47;break;
//		case 4: res -= 1.66;break;
//#endif
//		default:break;
//	}
//	printf("\r\n red%d = %5.2f",position,res);
	if(res > 175.49f)	// 199°C
		return 999.99;
	
	for(i = 0;i < 210;i++)
	{
		if(res == temp2res[i])
		{
			if(i < 10)	// 零下
				return i * 1.00f - 10.00f;
			else
				return i * 1.00f - 10.00f;
		}
		if(res > temp2res[i] && res < temp2res[i + 1])
		{
			if(i < 10) // 零下
			{
				return (res - temp2res[i]) / (temp2res[i + 1] - temp2res[i]) * 1.00f + i * 1.00f - 10.00f;
			}
			else
				return (res - temp2res[i]) / (temp2res[i + 1] - temp2res[i]) * 1.00f + i * 1.00f - 10.00f;
		}
	}
	return -10.00;
}

unsigned char purify_board_msg_src_heat[MAX_PID_NUM];
unsigned char purify_board_msg_src_shake[MAX_NUM_SHAKE];

void purification_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("purification board data proc\n");
    unsigned char op_code = data[0];
    //temperature quantity
    if(op_code == SUB_TEMPORATURE)
    {
        if(lenIn >= 4)
        {
            unsigned short tempQuan = data[2] + (data[3]<<8);
            printf("chan:%d,quantity[%d],temperature[%f]\n",data[1],tempQuan,convertTemperature(tempQuan));               
        }

        if(lenIn == 7)
        {
            unsigned short tempQuan = data[5] + (data[6]<<8);
            printf("chan:%d,quantity[%d],temperature[%f]\n",data[4],tempQuan,convertTemperature(tempQuan));  
        }
    }
    else if(op_code == SUB_PARAMETER)
    {
        float pidValue = 0;
        memcpy(&pidValue,&data[2],4);
        printf("chan:%d,pidvalue[%f],dutycycle[%d]\n",data[1], pidValue,data[6]);
    }
    else if(SUB_ROTATE == op_code)
    {
        int rotateSpeed = 0;
        memcpy(&rotateSpeed,&data[2],4);
        printf("chan:%d,rotateSpeed[%d]\n",data[1], rotateSpeed);
    }
    else if(PURIFY_TEMPERATURE == op_code)
    {
        if(lenIn<=2)
        {
            //start or stop report temp ack;
            int chanNumTmp = data[1];
            if(purify_board_msg_src_heat[chanNumTmp] == MSG_FROM_LUA)
            {
                sendAckToLua(SUBBOARD_BASE+(PURIFICATION_BOARD<<5)+chanNumTmp,CHECK_MOVE_END);
            }
            
        }
        else if(lenIn>=4)
        {
            unsigned short tempShort = 0;
            memcpy(&tempShort,data+2,2);
            float temp_f = convertTemperature(tempShort);
            printf("heat shake, chan:%d,temp:%f\n",data[1],temp_f);
            
            report_up_msg msgReport;
            msgReport.type = NOTIFY_CURR_TEMP;
            msgReport.dataLen = sizeof(temp_report_msg);
            msgReport.un_msg_data.tempReportMsg.boardId = PURIFICATION_BOARD;
            msgReport.un_msg_data.tempReportMsg.chanNum = data[1];
            msgReport.un_msg_data.tempReportMsg.currTemp = temp_f;

            sendSockNotifyMsg(&msgReport);
        }
    }
    else if(PURIFY_SHAKE == op_code)
    {
        if(lenIn >= 2)
        {
            unsigned char chanNumTmp = data[1];
            if(chanNumTmp >= MAX_NUM_SHAKE)
            {                
                return;
            }
            if(purify_board_msg_src_shake[chanNumTmp] == MSG_FROM_LUA)
            {
                sendAckToLua(SUBBOARD_BASE+(PURIFICATION_BOARD<<5)+chanNumTmp + PURIFY_SHAKE_BASE,CHECK_MOVE_END);
            }
        }
    }
    else if(PURIFY_HEAT == op_code)
    {
        if(lenIn >= 2)
        {
            unsigned char chanNumTmp = data[1];
            if(chanNumTmp >= MAX_PID_NUM)
            {                
                return;
            }
            if(purify_board_msg_src_heat[chanNumTmp] == MSG_FROM_LUA)
            {
                sendAckToLua(SUBBOARD_BASE+(PURIFICATION_BOARD<<5)+chanNumTmp + PURIFY_HEAT_BASE,CHECK_MOVE_END);
            }
        }
    }
    
}

void thermal_seal_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    //printf("thermal_seal board data proc\n");
    unsigned char op_code = data[0];

    if(op_code == SUB_TEMPORATURE)
    {
        // if(lenIn >= 4)
        // {
        //     unsigned int tempQuan = data[2] + (data[3]<<8);
        //     //printf("chan:%d,temperature[%f]uV\n",data[1],tempQuan*62.5); 
            
        //     int lenTmp = 0;
        //     numData ++;
        //     if(numData<20)
        //     {
        //        lenTmp = snprintf(strToWrite+lenInStr,1024-lenInStr,"%f\t",tempQuan*0.0000625);
        //     }
        //     else
        //     {
        //         /* code */
        //         lenTmp = snprintf(strToWrite+lenInStr,1024-lenInStr,"%f\r\n",tempQuan*0.0000625);
        //         numData = 0;
        //     }
    
        //     lenInStr += lenTmp;
            
        //     if(lenInStr>=900)
        //     {
        //         if(fd_data_temp!=-1)
        //         {
        //             write(fd_data_temp,strToWrite,lenInStr);
        //         }
        //         else
        //         {
        //             /* code */
        //         }
                
        //         lenInStr = 0; 
        //     }              
        // }

        // if(lenIn == 7)
        // {
        //     unsigned int tempQuan = data[5] + (data[6]<<8);
        //     printf("chan:%d,temperature[%f]uV\n",data[4],tempQuan*62.5);  
        // }
        float temp = 0;
        memcpy((char*)&temp,data+3,4);

        if(data[1] == 2)
        {
            checkAndReportTemp(THERMAL_SEAL_BOARD,CHAN_TEMP_SEAL_BASE,temp);
        }

        printf("chan[%d],temp[%f]\n",data[1],temp);
    }
}

void setQpcrGrpReport(int qpcrId, int interv_ms)
{
    int tempReadChanBase = CHAN_TEMP_Q3_BASE;
    if(qpcrId)
    {
        tempReadChanBase = CHAN_TEMP_Q4_BASE;
    }
    int i = 0;    

    for(i=0;i<MAX_CHAN_ONE_QPCR;i++)
    {
        setTempReportCtl(tempReadChanBase, i, interv_ms);
    }
}

void setTempReportCtl(int chanBaseIndex, int chanNumIn, int interv_ms)
{
    int chanNum = chanBaseIndex+chanNumIn;
    
    printf("in setTempReportCtl,chan[%d],interv_ms[%d]\n",chanNum,interv_ms);
    if(chanNum >= MAX_CHAN_TEMP_NUM || chanNum < 0)
    {
       return;
    }
    
    if(interv_ms == 0)
    {
        //tempReportCtlArr[chanNum].count_tar = interv_ms/100;
        //tempReportCtlArr[chanNum].count_curr = 0;
        tempReportCtlArr[chanNum].needReport = 0;
    }
    else
    {
        tempReportCtlArr[chanNum].count_tar = interv_ms/100;
        tempReportCtlArr[chanNum].count_curr = 0;
        tempReportCtlArr[chanNum].needReport = 1;
    }   


}

int checkAndReportTemp(int boardId, int chanNumIn, float temperatureIn)
{

    //printf("checkAndReportTemp 111,chanNumIn:%d\n",chanNumIn);
     
    if(chanNumIn >= MAX_CHAN_TEMP_NUM || chanNumIn < 0)
    {
       return -1;
    }

    //printf("checkAndReportTemp 222,need:%d,targetCnt:%d\n",
    //tempReportCtlArr[chanNumIn].needReport,
    //tempReportCtlArr[chanNumIn].count_tar);

    if((!tempReportCtlArr[chanNumIn].needReport) 
    || (tempReportCtlArr[chanNumIn].count_tar <= 0))
    {
       return -2;
    }

    //printf("checkAndReportTemp 333\n");
    
    tempReportCtlArr[chanNumIn].count_curr ++ ;

    if(tempReportCtlArr[chanNumIn].count_curr >= tempReportCtlArr[chanNumIn].count_tar)
    {
        tempReportCtlArr[chanNumIn].count_curr = 0;

        report_up_msg reportMsg;
        memset(&reportMsg,0,sizeof(report_up_msg));
        reportMsg.type = NOTIFY_CURR_TEMP;
        reportMsg.dataLen = sizeof(int);
        reportMsg.un_msg_data.tempReportMsg.boardId = boardId;
        reportMsg.un_msg_data.tempReportMsg.chanNum = chanNumIn;
        reportMsg.un_msg_data.tempReportMsg.currTemp = temperatureIn;
        sendSockNotifyMsg(&reportMsg);
        printf("report temp now\n");  
    }
    return 0;    
}

temperature_report_ctl  tempReportCtlArr[MAX_CHAN_TEMP_NUM];

void initTempReportCtl(void)
{
    memset(tempReportCtlArr,0,sizeof(temperature_report_ctl)*MAX_CHAN_TEMP_NUM);
}

#ifdef _QPCR
void qpcr_ctrl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    
    printf("qpcr_ctrl board data proc\n");

    unsigned char lenData = lenIn-1;
    for(int i=0;i<lenData;i++)
    {
        printf("%02x,",data[i+1]);
    }
    printf("\n");

    if(lenIn<3)
    {
        printf("can data len is too short,len[%d]\n",lenIn+1);
    }
    
    recvSubBoardGram dataFromQpcrBoard;
    memset(&dataFromQpcrBoard,0,sizeof(recvSubBoardGram));

    dataFromQpcrBoard.boardId = 0x06;
    dataFromQpcrBoard.opCode = data[0];
    dataFromQpcrBoard.chanNum = data[1];
    dataFromQpcrBoard.paramType = data[2];

    switch(dataFromQpcrBoard.opCode)
    {
        case SUB_ALARM:
        {
            float temperature = .0;
            memcpy(&temperature,&data[3],sizeof(float));
            dataFromQpcrBoard.un_paramData.value_f = temperature;

            printf("alarm, temperature[%f] in chan[%d] exceed the stadard\n",
            temperature,
            dataFromQpcrBoard.chanNum);
        }
        break;
        case SUB_TEMPORATURE:
        {
            float temperature = .0;
            memcpy(&temperature,&data[3],sizeof(float));
            dataFromQpcrBoard.un_paramData.value_f = temperature;

            printf("Q1, in chan[%d],temperature[%f] is received\n",
            dataFromQpcrBoard.chanNum,
            temperature);

            unsigned char chanTemp = dataFromQpcrBoard.chanNum;

            if(chanTemp == 9)//for hot lid
            {
                chanTemp = 1;
            }
            else if(chanTemp>=1 && chanTemp<=5)
            {
                chanTemp = chanTemp-1;
            }
            

            checkAndReportTemp(QPCR_CTRL_BOARD, chanTemp + CHAN_TEMP_Q1_BASE, temperature);
            checkAndReportTemp(QPCR_CTRL_BOARD, chanTemp + CHAN_TEMP_Q3_BASE, temperature);
        }
        break;
        case SUB_ECHO:
        {

        }
        break;
        case SUB_MOVE:
        {
            
        }
        break;
        case SUB_ACK:
        {
            
        }
        break;
        case SUB_INTERRUPT:
        {
            
        }
        break;
        case SUB_NOTIFY:
        {
            printf("notify received,\n");
            if(dataFromQpcrBoard.chanNum == 0xff 
            &&dataFromQpcrBoard.paramType == QPCR_PHOTO)
            {
                memcpy(&dataFromQpcrBoard.un_paramData.value_i,&data[3],4);
                char timeStrBuff[128];
                memset(timeStrBuff,0,128);
                getCurrTime(timeStrBuff);
                printf("%s,photo notify,\n",timeStrBuff);

                printf("qpcr_ctrl_data_proc ready for taking photo now\n");
#ifdef _GP_ALPHA

                key_t key = ftok(msgNotifyQueuePath, keyNotifyMsg);
                if(key < 0)
                {
                    printf("%s\n",msgNotifyQueuePath);
                    perror("ftok");                    
                    return;
                }

                int msg_id = msgget(key, 0600);//IPC_CREAT|0600
                if(msg_id < 0)
                {
                    perror("msgget");
                    return;
                }
                else
                {

                    printf("send photo notification to pc\n");

                    report_up_queue ctlFrame;
                    memset(&ctlFrame,0,sizeof(report_up_queue));
                    report_up msgFrame;

                    ctlFrame.type = QUEUE_MSG_TYPE_REPORT;


                    if(msgsnd(msg_id, (void*)&ctlFrame, sizeof(report_up), 0) < 0)
                    {
                        perror("msgsnd");
                        return;
                    }
                    else
                    {
                        /* code */
                        printf("send pc success,type is %d\n",ctlFrame.type);
                    }


                }
#else
                report_up_msg reportMsg;
                memset(&reportMsg,0,sizeof(report_up_msg));
                reportMsg.type = NOTIFY_QPCR_PHOTO;
                reportMsg.dataLen = sizeof(int);
                reportMsg.un_msg_data.qpcrNotify = 0;
                int isStart = 1;
                reportMsg.un_msg_data.qpcrNotify += (isStart<<16);
                sendSockNotifyMsg(&reportMsg); 
#endif

                
                // if(dataFromQpcrBoard.un_paramData.value_i==1)
                // {
                //     printf("ready for taking photo now\n");
                // }
                // else
                // {
                //     printf("it is NOT ready for taking photo\n");
                // }
            }
            
        }
        break;
        case SUB_PARAMETER:
        {
            if( dataFromQpcrBoard.paramType >= QPCR_KPR 
              &&dataFromQpcrBoard.paramType <= QPCR_CT)
            {
                memcpy(&dataFromQpcrBoard.un_paramData.value_f,&data[3],4); 
                if(dataFromQpcrBoard.paramType<=QPCR_DTF)
                {
                    printf("kpi param received\n");
                }
                else
                {
                    printf("temerature param received\n");
                }

                
                printf("%s for chan[%02x] is %f\n",
                str_qpcr[dataFromQpcrBoard.paramType],
                dataFromQpcrBoard.chanNum,
                dataFromQpcrBoard.un_paramData.value_f);
            }
            else if(   dataFromQpcrBoard.paramType >= QPCR_HKT
                    && dataFromQpcrBoard.paramType <= QPCR_LST)
            {
                memcpy(&dataFromQpcrBoard.un_paramData.value_i,&data[3],4);
                printf("time param received\n");
                printf("%s for chan[%02x] is %d\n",
                str_qpcr[dataFromQpcrBoard.paramType],
                dataFromQpcrBoard.chanNum,
                dataFromQpcrBoard.un_paramData.value_i);
            }             

        }
        break;

        default:
        break;
    }

}
#else
void qpcr_ctrl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("qpcr_ctrl board data proc, should not recv data in purify centre board\n");
}
#endif

void qpcr1_ctrl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    
    printf("qpcr1_ctrl board data proc\n");

    unsigned char lenData = lenIn-1;
    for(int i=0;i<lenData;i++)
    {
        printf("%02x,",data[i+1]);
    }
    printf("\n");

    if(lenIn<3)
    {
        printf("can data len is too short,len[%d]\n",lenIn+1);
    }
    
    recvSubBoardGram dataFromQpcrBoard;
    memset(&dataFromQpcrBoard,0,sizeof(recvSubBoardGram));

    dataFromQpcrBoard.boardId = 0x06;
    dataFromQpcrBoard.opCode = data[0];
    dataFromQpcrBoard.chanNum = data[1];
    dataFromQpcrBoard.paramType = data[2];

    switch(dataFromQpcrBoard.opCode)
    {
        case SUB_NOTIFY:
        {
            printf("notify received,\n");
            if(dataFromQpcrBoard.chanNum == 0xff 
            &&dataFromQpcrBoard.paramType == QPCR_PHOTO)
            {
                memcpy(&dataFromQpcrBoard.un_paramData.value_i,&data[3],4);
                printf("photo notify,\n");

                printf("qpcr_ctrl_data_proc1 ready for taking photo now\n");
#ifdef _GP_ALPHA
                key_t key = ftok(msgNotifyQueueQ1Path, keyNotifyMsg_1);
                if(key < 0)
                {
                    printf("%s\n",msgNotifyQueueQ1Path);
                    perror("ftok");                    
                    return;
                }

                int msg_id = msgget(key, 0600);//IPC_CREAT|0600
                if(msg_id < 0)
                {
                    perror("msgget");
                    return;
                }
                else
                {

                    printf("send photo notification to pc\n");

                    report_up_queue ctlFrame;
                    memset(&ctlFrame,0,sizeof(report_up_queue));
                    report_up msgFrame;

                    ctlFrame.type = QUEUE_MSG_TYPE_REPORT;


                    if(msgsnd(msg_id, (void*)&ctlFrame, sizeof(report_up), 0) < 0)
                    {
                        perror("msgsnd");
                        return;
                    }
                    else
                    {
                        /* code */
                        printf("send pc success,type is %d\n",ctlFrame.type);
                    }

                }
#else
                report_up_msg reportMsg;
                memset(&reportMsg,0,sizeof(report_up_msg));
                reportMsg.type = NOTIFY_QPCR_PHOTO;
                reportMsg.dataLen = sizeof(int);
                reportMsg.un_msg_data.qpcrNotify = 1;
                int isStart = 1;
                reportMsg.un_msg_data.qpcrNotify += (isStart<<16);
                sendSockNotifyMsg(&reportMsg); 
#endif


                
                // if(dataFromQpcrBoard.un_paramData.value_i==1)
                // {
                //     printf("ready for taking photo now\n");
                // }
                // else
                // {
                //     printf("it is NOT ready for taking photo\n");
                // }
            }
            
        }
        break;
        case SUB_TEMPORATURE:
        {
            float temperature = .0;
            memcpy(&temperature,&data[3],sizeof(float));
            dataFromQpcrBoard.un_paramData.value_f = temperature;

            printf("Q2, in chan[%d],temperature[%f] is received\n",
            dataFromQpcrBoard.chanNum,
            temperature);

            unsigned char chanTemp = dataFromQpcrBoard.chanNum;

            if(chanTemp == 9)//for hot lid
            {
                chanTemp = 1;
            }
            else if(chanTemp>=1 && chanTemp<=5)
            {
                chanTemp = chanTemp-1;
            }
            checkAndReportTemp(QPCR_CTRL_BOARD_1, chanTemp + CHAN_TEMP_Q2_BASE, temperature);
            checkAndReportTemp(QPCR_CTRL_BOARD_1, chanTemp + CHAN_TEMP_Q4_BASE, temperature);
        }
        break;
        

        default:
        break;
    }

}


void system_ctrl_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    printf("system_ctrl board data proc\n");
    unsigned char lenData = lenIn-1;
    // for(int i=0;i<lenData;i++)
    // {
    //     printf("%02x,",data[i+1]);
    // }
    // printf("\n");

    if(lenIn<3)
    {
        return;
    }
    unsigned char op_code = data[0];
    unsigned char chanNum = data[1];
    unsigned char type = data[2];
    
    recvDataEleCtl * pstCheckData = (recvDataEleCtl *)dataOut;

    switch(op_code)
    {
        case SUB_MOVE:
        {
            if(type==LIQUID_ACT_FINISHED)
            {
                pstCheckData->sid = 84+chanNum;                
                pstCheckData->frameType = CHECK_MOVE_END;
                printf("ele with num[%d] move finished\n",chanNum);

                sendAckToGrpc(0,0,84+chanNum,-1);
            }
        }
        break;
        default:
        break;
    }
}


void encap_pid_gram(pidConfig * configIn,int sidIn,int * numOut, void * dataOut )
{
    can_frame * framOut = (can_frame *)dataOut;
    int count = 0;
    if(configIn->pidOpcode==CENTRE_START || configIn->pidOpcode==CENTRE_STOP)
    {
        framOut->can_id = sidIn;//0x305

        framOut->data[0] = configIn->pidOpcode;
        framOut->data[1] = configIn->pidChum;
        framOut->can_dlc = 2;

        *numOut = 1;
        return;

    }

    framOut->can_id = sidIn;//0x305

    framOut->data[0] = CENTRE_CONFIG;
    framOut->data[1] = configIn->pidChum;
    framOut->data[2] = PID_KP;
    memcpy(framOut->data+3,(char*)&configIn->kp,4);
    framOut->can_dlc = 7;

    framOut++;
    count++;

    framOut->can_id = sidIn;//0x305
    framOut->data[0] = CENTRE_CONFIG;
    framOut->data[1] = configIn->pidChum;
    framOut->data[2] = PID_KI;
    memcpy(framOut->data+3,(char*)&configIn->ki,4);
    framOut->can_dlc = 7;

    framOut++;
    count++;

    framOut->can_id = sidIn;//0x305
    framOut->data[0] = CENTRE_CONFIG;
    framOut->data[1] = configIn->pidChum;
    framOut->data[2] = PID_KD;
    memcpy(framOut->data+3,(char*)&configIn->kd,4);
    framOut->can_dlc = 7;

    framOut++;
    count++;

    framOut->can_id = sidIn;//0x305
    framOut->data[0] = CENTRE_CONFIG;
    framOut->data[1] = configIn->pidChum;
    framOut->data[2] = PID_TAR;
    memcpy(framOut->data+3,(char*)&configIn->target,4);
    framOut->can_dlc = 7;

    count++;

    *numOut = count;
}

void encap_cap_gram(unsigned char op_code, unsigned short chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x303;
    framOut->data[0] = op_code;
    framOut->data[1] = 0;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case CAP_SAMPLE:
        {
            if(op_code==CENTRE_START)
            {
                int i = 0;
                //here the channum should be channel mask
                framOut->data[3] = chanNum&0x00ff;
                framOut->data[4] = (chanNum>>8)&0x00ff;
                framOut->can_dlc = 5;
                for(i=0;i<max_chan_num[CAP_DETECT_BOARD];i++)
                {
                    if(chanNum&(1<<i))
                    {
                        framOut->data[1] ++;
                    }
                }
            }

        }        
        break;
        case CAP_PROBE_LIQUID:
        {
            if(op_code==CENTRE_START)
            {
                int i = 0;
                //here the channum should be channel mask
                framOut->data[3] = chanNum&0x00ff;
                framOut->data[4] = (chanNum>>8)&0x00ff;
                framOut->can_dlc = 5;
                for(i=0;i<max_chan_num[CAP_DETECT_BOARD];i++)
                {
                    if(chanNum&(1<<i))
                    {
                        framOut->data[1] ++;
                    }
                }
            }

        }        
        break;
        case CAP_DELATA_ENV_LIQUID:
        case CAP_DELATA_ENV_TIP:
        case CAP_DELATA_ENV_SUCK:
        {
            if(op_code==CENTRE_CONFIG)
            {
                int i = 0;
                //here the channum should be channel mask
                unsigned short * delta = (unsigned short *)paramData;
                framOut->data[3] = (*delta)&0x00ff;
                framOut->data[4] = ((* delta)>>8)&0x00ff;
                framOut->can_dlc = 5;                
            }

        }        
        break;

        default:
        break;
    }
    
}

void encap_qpcr_gram(int qpcrId, unsigned char op_code, void * ctlData, void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;
    qpcrCtl * pstCtlData = (qpcrCtl *)ctlData;


    framOut->can_id = qpcrId?0x308:0x306;

    framOut->data[0] = op_code;
    framOut->data[1] = pstCtlData->chanNum;
    framOut->data[2] = pstCtlData->paramType;
    framOut->can_dlc = 3;
    if(pstCtlData->paramType >=QPCR_KPR && pstCtlData->paramType <=QPCR_CT )
    {
       //framOut->data[3] = (pstCtlData->paramDataf & 0x000000ff);

        memcpy(&framOut->data[3],&pstCtlData->paramDataf,4);
        framOut->can_dlc += 4;
    }
    else if(pstCtlData->paramType >=QPCR_HKT && pstCtlData->paramType <=QPCR_LST)
    {
        memcpy(&framOut->data[3],&pstCtlData->paramDataI,4);
        framOut->can_dlc += 4;
    }

	if(op_code == CENTRE_START || op_code == CENTRE_STOP)
	{
	     int boardId = qpcrId? QPCR_CTRL_BOARD_1:QPCR_CTRL_BOARD;
	     sendAckToLua(SUBBOARD_BASE+(boardId<<5)+pstCtlData->chanNum,CHECK_MOVE_END);
	}
    
}

unsigned int calcStrSum(int lenIn, unsigned char * strIn)
{
	unsigned int sumTmp = 0;

	int lenLeft = lenIn - 1;


	while(lenLeft >= 0)
	{
		sumTmp += strIn[lenLeft];
		lenLeft--;
	}

	return sumTmp;
}

void sendQpcrSheme(int qpcrIdIn, void * pstCanIn)//CCan *
{
    unsigned char strBuff[1024] = {0};
	int lenStr = 0;
    char fileName[256];
    memset(fileName,0,256);
    sprintf(fileName,"%s%d%s","/mnt/nandflash/apps/tmp/qpcr",qpcrIdIn,"_scheme.txt");
	FILE * fp = fopen(fileName,"r");

	if(fp==NULL)
	{
		printf("open file %s failed\n",fileName);
		return;
	}
    CCan * pstCan = (CCan *)pstCanIn;
    unsigned short boardId = qpcrIdIn?0x308:0x306;

    memset(strBuff,0,1024);
	
	int sendByte = 0;
	strBuff[0] = 0x23;
	strBuff[1] = 0x01;
	strBuff[2] = 0x01;
	char * strRet = fgets((char *)(&strBuff[3]),1020,fp);
	printf("string from file:%s,len:%d\n",(char *)(&strBuff[3]),strlen((char *)(&strBuff[3])));

	lenStr = strlen((char *)(&strBuff[3]));
	//strBuff[lenStr-1] = '\0';
	//lenStr += 2;//- /n  + 3
	int bytesOnce = 0;
	int i = 0;
	unsigned int sumOnce = 0;
	unsigned int sumAll = 0x02;
	sumAll += calcStrSum(lenStr-1,&strBuff[3]);

	strBuff[lenStr+2] = sumAll & 0x00ff;
	strBuff[lenStr+3] = 0x5C;
	lenStr += 4;
	while(lenStr>0)
	{ 
		sumOnce = 0;     
        
		bytesOnce = pstCan->sendString(boardId,lenStr, strBuff);
        //sumAll += sumOnce;
		sendByte += bytesOnce;
        printf("send %d bytes %dth time\n",bytesOnce,i++);
		memset(strBuff,0,1024);
	    strBuff[0] = 0x23;
	    strBuff[1] = 0x01;
	    strBuff[2] = 0x01;
		strRet = fgets((char *)(&strBuff[3]),1020,fp);
        
		if(!strRet)
		{
			printf("read string from file failed\n");
			break;
		}
      
		lenStr = strlen((char *)(&strBuff[3]));
        printf("string from file:%s,len:%d\n",(char*)strBuff,lenStr);
        sumAll = 0x02;
		sumAll += calcStrSum(lenStr-1,&strBuff[3]);
        strBuff[lenStr+2] = sumAll & 0x00ff;
	    strBuff[lenStr+3] = 0x5C;
	    lenStr += 4;		
 
	}

	printf("send out %d bytes\n",sendByte);  
	if(fp)
    {
	    fclose(fp);
    }

}

void encap_qpcr_gram_en(int qpcrId, unsigned char op_code, void * ctlData, void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;
    qpcrCtl * pstCtlData = (qpcrCtl *)ctlData;


    framOut->can_id = qpcrId?0x308:0x306;
    framOut->data[0] = 0x23;
    framOut->data[1] = op_code;
    framOut->data[2] = op_code;
    framOut->data[3] = 0x5c;
    framOut->can_dlc = 4;
    
    if(LIGHT_CTL == op_code)
    {
       unsigned char op_code_last = CENTRE_QPCR_QLIGHT;
       if(pstCtlData->chanNum == LIGHT_QPCR_SOURCE)
       {
           op_code_last = CENTRE_QPCR_QLIGHT;
       }
       else
       {
           op_code_last = CENTRE_QPCR_ENLIGHT;
       }

       framOut->data[1] = op_code_last;       
       framOut->data[2] = pstCtlData->paramDataI & 0x00ff;
       framOut->data[3] = framOut->data[2] + framOut->data[1];
       framOut->data[4] = 0x5c; 
       framOut->can_dlc = 5;
    }

	if(op_code == CENTRE_START 
    || op_code == CENTRE_STOP 
    || op_code == LIGHT_CTL)
	{
	     int boardId = qpcrId? QPCR_CTRL_BOARD_1:QPCR_CTRL_BOARD;
	     sendAckToLua(SUBBOARD_BASE+(boardId<<5)+pstCtlData->chanNum,CHECK_MOVE_END);
	}    
    
}

void encap_qpcr_gram_and_send(int qpcrId, unsigned char op_code, void * ctlData,void * pstCanIn)
{
    int count = 0;

    unsigned char sendBuff[128];

    memset(sendBuff,0,128);
    int lenStr = 0;

    CCan * pCanHanle = (CCan *)pstCanIn;

    if(pCanHanle==NULL)
    {
        return ;
    }
    
    if(HEAT_CTL)
    {
       unsigned char op_code_last = CENTRE_CONFIG;
       unsigned char configId = 0x02;//for hot lid

       sendBuff[0] = 0x23;
       sendBuff[1] = op_code_last;
       sendBuff[2] = configId;


       heatParam * pstHeatParam = (heatParam *)ctlData;

       if(pstHeatParam->opcode == CENTRE_START)
       {
           memcpy(sendBuff+3,&(pstHeatParam->temperature),4);
       }
       else
       {
           memset(sendBuff+3,0,4);
       }

       unsigned int sumData = calcStrSum(6,sendBuff+1);

       sendBuff[7] =  sumData & 0x00ff;

       sendBuff[8] = 0x5c;
       unsigned short boardCanId =  qpcrId ? 0x308:0x306;
       int lenSend = pCanHanle->sendString(boardCanId,9,sendBuff);

       if(lenSend>0)
       {
           printf("send to 0x%04x,%d bytes\n",boardCanId,lenSend);
        //    char printBuff[128] = {0};
        //    sprintf(printBuff,"%02x",sendBuff[0]);
        //    for(int i=1;i<lenSend;i++)
        //    {
        //        sprintf(printBuff,"%s %02x",printBuff,sendBuff[i]);
        //    }
        //    printf("%s\n",printBuff);
       }

        int chanTempBase = CHAN_TEMP_Q1_BASE;
        if(qpcrId)
        {
            chanTempBase = CHAN_TEMP_Q2_BASE;
        }
        int interv = 0;
        if(pstHeatParam->opcode == CENTRE_START)
        {
           interv = 2000;

        }
        else
        {
           interv = 0;
        }
       

       setTempReportCtl(chanTempBase,1,interv);

       int boardId = qpcrId? QPCR_CTRL_BOARD_1:QPCR_CTRL_BOARD;
	   sendAckToLua(SUBBOARD_BASE+(boardId<<5)+pstHeatParam->chan,CHECK_MOVE_END);
        
    }
}

void encap_thermal_gram(unsigned char op_code, unsigned char chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x305;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case CAP_SAMPLE:
        break;
        case THERMAL_HEAT:
        {
        }
        break;
        default:
        break;
    }
    
}

void encap_thermal_gram_en(unsigned char op_code, unsigned char chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x305;
    framOut->data[0] = 0x23;
    framOut->data[1] = op_code;
    framOut->data[2] = chanNum;
    framOut->data[3] = op_code + chanNum;
    framOut->data[4] = 0x5c;
    framOut->can_dlc = 5;
    switch(paramTypeIn)
    {
        case THERMAL_HEAT:
        {
            if(op_code == CENTRE_CONFIG)
            {
                unsigned char * pDataf = (unsigned char *)paramData;
                memcpy(&framOut->data[2],pDataf,4);
                framOut->data[6] = calcStrSum(5,&framOut->data[1]);
                framOut->data[7] = 0x5c;
                framOut->can_dlc = 8;
            }
        }
        break;

        default:
        break;
    }
    
}

void encap_purify_gram(unsigned char op_code, unsigned short chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x304;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case PURIFY_DUTYCYCLE:
        {
            unsigned char * dutyCycle = &(((purifyCtl *)paramData)->dutyCycle);
            framOut->can_dlc = 5;
            framOut->data[3] = *dutyCycle;
            framOut->data[4] = 0;
        }
        break;
        case PURIFY_SHAKE:
        {
            int * ptrDuration = &(((purifyCtl *)paramData)->duration);
            framOut->can_dlc = 7;
            memcpy(framOut->data+3,ptrDuration,4);
        }
        break;
        case PURIFY_HEAT:
        {
            if(op_code == CENTRE_START)
            {
                float * ptrTemprature = (float *)paramData;
                memcpy(framOut->data+3,ptrTemprature,4);
                framOut->can_dlc += 4;
            }
            
        }
        break;
        case PURIFY_ROTATE_SPEED_CNT:
        {
            if(op_code == CENTRE_CONFIG)
            {
                unsigned short * targetRotateSpeed = 
                &(((purifyCtl *)paramData)->rotateSpeedCnt);
                memcpy(framOut->data+3,targetRotateSpeed,2);
                framOut->can_dlc = 5;
            }
            
        }
        break;
        case PURIFY_TEMPERATURE:
        {
            if(op_code == CENTRE_START || op_code == CENTRE_STOP)
            {
                unsigned int interv = *((unsigned int *)paramData);
                memcpy(framOut->data+3,&interv,sizeof(int));
                framOut->can_dlc += 4;
            }
            
        }
        break;
        default:
        break;
    }  
}

void encap_djctl_gram(unsigned char op_code, unsigned short chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x307;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case SYSCTL_LIQUID:
        {
            if(op_code == CENTRE_START)
            {
                int * duration = (int *)paramData;
                memcpy(&framOut->data[3],duration,4);
                framOut->can_dlc = 7;
            }
        }
        break;
        default:
        break;
    }
}

void encap_io_expand_gram(unsigned char op_code, unsigned short chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x302;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case SYSCTL_LIQUID:
        {
            if(op_code == CENTRE_START)
            {
                int * duration = (int *)paramData;
                memcpy(&framOut->data[3],duration,4);
                framOut->can_dlc = 7;
            }
        }
        break;
        default:
        break;
    }
}

void encap_scancode_gram(unsigned char op_code, unsigned short chanNum, 
unsigned char paramTypeIn, void * paramData,void * dataOut)
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0x30a;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = paramTypeIn;
    framOut->can_dlc = 3;
    switch(paramTypeIn)
    {
        case SCANCODE_SCAN:
        {
            if(op_code == CENTRE_START)
            {
                if(!g_barcode_handle)
                {
                    g_barcode_handle = new CBarcode();
                    
                }
                g_barcode_handle->init_one_chan(chanNum);
            }
            else if(op_code == CENTRE_STOP)
            {
                if(g_barcode_handle)
                {
                    
                    g_barcode_handle->stop_one_chan(chanNum);                    
                }
                
            }

        }
        break;
        default:
        break;
    }   
}

void air_pressure_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{

}
void scancode_data_proc(unsigned char lenIn, unsigned char * data,void*dataOut)
{
    unsigned char opcode = data[0];

    if(opcode == SUB_BARCODE)
    {
        unsigned char chanNum = data[1]&0x3f;
        unsigned char frameType = ((data[1]&0x00c0) >> 6);

        unsigned char dataLen = data[2];

        if(g_barcode_handle)
        {
            g_barcode_handle->addPartStr(chanNum,frameType,data+3,dataLen);
        }
    }

}

CDataFile::CDataFile(const char* fileName,const int buffSize=MAX_DATA_BUFF)
{
    if(fileName==NULL)
    {
        dataFiles = NULL;
        return;
    }
    dataFiles = new dataFile[1];

    dataFiles->m_fd = 0;

    char fileNameStr[256];
    const char * ptrName = NULL;
    memset(fileNameStr,256,0);

    struct timeval tv;
    gettimeofday(&tv,NULL);

    ptrName = strchr(fileName,'.');

    if(ptrName)
    {
        int len = ptrName-fileName;
        memcpy(fileNameStr,fileName,len);

        len += sprintf(fileNameStr+len,"_%d",tv.tv_sec);
        len += sprintf(fileNameStr+len,"%s",ptrName);
    }
    else
    {
        int len = strlen(fileName);
        memcpy(fileNameStr,fileName,len);

        len += sprintf(fileNameStr+len,"_%d",tv.tv_sec);
    }

    dataFiles->m_fd = fopen(fileNameStr,"w");
    if(dataFiles->m_fd==NULL)
    {
        printf("openfile failed\n");
        return;
    }
    dataFiles->m_buff = new char[buffSize]; 

    memset(dataFiles->m_buff,0,buffSize);
    dataFiles->dataNum = 0;
    dataFiles->m_currBufSize = 0;

    maxChanNum = 1;   
}

CDataFile::CDataFile(const char* fileName,int boardId, const int chanMask,const int buffSize)
{
    if(fileName==NULL || chanMask==0)
    {
        dataFiles = NULL;
        return;
    }

    int fileIndex = 0;
    fileChanNum = new int[max_chan_num[boardId]];
    memset(fileChanNum,-1,sizeof(int)*max_chan_num[boardId]);
    
    int *fileIToChanNum  = new int[max_chan_num[boardId]];
    memset(fileIToChanNum,-1,sizeof(int)*max_chan_num[boardId]);

    for(int i=0;i<max_chan_num[boardId];i++)
    {
        if((1<<i)&chanMask)
        {
            fileChanNum[i] = fileIndex;
            fileIToChanNum[fileIndex] = i;
            fileIndex++; 
        }
    }

    
    
    dataFiles = new dataFile[fileIndex];

    memset(dataFiles,0,sizeof(dataFile)*fileIndex);

    char fileNameStr[256];
    const char * ptrName = NULL;
    memset(fileNameStr,0,256);

    struct timeval tv;
    gettimeofday(&tv,NULL);

    ptrName = strchr(fileName,'.');

    for(int i=0;i<fileIndex;i++)
    {
        memset(fileNameStr,0,sizeof(char)*256);
        if(ptrName)
        {
            int len = ptrName-fileName;
            memcpy(fileNameStr,fileName,len);

            len += sprintf(fileNameStr+len,"_chan%d_%d",fileIToChanNum[i],tv.tv_sec);
            len += sprintf(fileNameStr+len,"%s",ptrName);
        }
        else
        {
            int len = strlen(fileName);
            memcpy(fileNameStr,fileName,len);

            len += sprintf(fileNameStr+len,"_chan%d_%d",fileIToChanNum[i],tv.tv_sec);
        }

        dataFiles[i].m_fd = fopen(fileNameStr,"w");
        if(dataFiles[i].m_fd==NULL)
        {
            printf("openfile failed\n");
            return;
        }
        dataFiles[i].m_buff = new char[buffSize]; 

        memset(dataFiles[i].m_buff,0,buffSize);
        dataFiles[i].dataNum = 0;
        dataFiles[i].m_currBufSize = 0;
    }
    maxChanNum = fileIndex; 
    delete fileIToChanNum;
}

CDataFile::~CDataFile()
{
    if(dataFiles!=NULL)
    {

        for(int i=0;i<maxChanNum;i++)
        {
            if(dataFiles[i].m_currBufSize)
            {
                if(this->isValid(i))
                {
                    writeToFile(i);
                }

                dataFiles[i].m_currBufSize = 0;             

            }

            if(dataFiles[i].m_fd)
            {
                fclose(dataFiles[i].m_fd);
                dataFiles[i].m_fd = NULL;
            }

            if(dataFiles[i].m_buff)
            {
                delete [] dataFiles[i].m_buff;
                dataFiles[i].m_buff = NULL;
            }

            dataFiles[i].dataNum = 0;
        }
        delete [] dataFiles; 
    }
    
    if(fileChanNum)
    {
        delete [] fileChanNum;
    }


}
int CDataFile::addToDataBuff(const char* data,int len)
{
    if(!this->isValid())
    {
        return -1;
    }
    

    if((len+dataFiles->m_currBufSize+2) < MAX_DATA_BUFF)
    {
        memcpy(dataFiles->m_buff+dataFiles->m_currBufSize,data,len);
        dataFiles->m_currBufSize += len;
    }
    else
    {
        writeToFile();
        memcpy(dataFiles->m_buff,data,len);
        dataFiles->m_currBufSize = len;
    }

    dataFiles->dataNum++;
    if(dataFiles->dataNum>=50)
    {
       dataFiles->m_buff[dataFiles->m_currBufSize++] = '\r';
       dataFiles->m_buff[dataFiles->m_currBufSize++] = '\n';
       dataFiles->dataNum=0; 
    }
}

int CDataFile::addToDataBuff(const char* data,int len, int chan)
{
    
    //printf("enter in addToDataBuff,chan[%d],maxChanNum[%d]\n",chan,maxChanNum);
    if(fileChanNum==NULL)//chan>=maxChanNum || 
    {
        return -1;
    }
    int fileIndex = fileChanNum[chan];

    if(!this->isValid(fileIndex))
    {
        printf("fileIndex is not valid,chan[%d],fileIndex[%d]\n",chan,fileIndex);
        return -1;
    }

    if((len+dataFiles[fileIndex].m_currBufSize+2) < MAX_DATA_BUFF)
    {
        memcpy(dataFiles[fileIndex].m_buff+dataFiles[fileIndex].m_currBufSize,data,len);
        dataFiles[fileIndex].m_currBufSize += len;
    }
    else
    {
        writeToFile(fileIndex);
        memcpy(dataFiles[fileIndex].m_buff,data,len);
        dataFiles[fileIndex].m_currBufSize = len;
    }

    dataFiles[fileIndex].dataNum++;
    if(dataFiles[fileIndex].dataNum>=50)
    {
       //dataFiles[fileIndex].m_buff[dataFiles[fileIndex].m_currBufSize++] = '\r';
       //dataFiles[fileIndex].m_buff[dataFiles[fileIndex].m_currBufSize++] = '\n';
       dataFiles[fileIndex].dataNum=0; 
    }
}

int CDataFile::writeToFile(int fileIndex)
{
    if(!dataFiles[fileIndex].m_fd)
    {
        return -1;
    }

    fwrite(dataFiles[fileIndex].m_buff,dataFiles[fileIndex].m_currBufSize,1,dataFiles[fileIndex].m_fd);
    fflush(dataFiles[fileIndex].m_fd);
    dataFiles[fileIndex].m_currBufSize = 0;

}

extern int g_exitFlag;

CDataFile * g_fileCapData = 0;
CDataFile * g_fileDataArr[MAX_BOARD_NUM];
extern CCan * g_subBoardCanHandle;

void *threadDataSample(void * param)
{
    key_t key = ftok(msgQueueKeyPath, 0x1234);
    if(key < 0)
    {
        printf("%s\n",msgQueueKeyPath);
        perror("ftok");
        printf("start thread for sampling failed\n");        
        return (void*)0;
    }

    sample_queue_msg msgSampleData;

    int msg_id = msgget(key, IPC_CREAT);
    if(msg_id < 0)
    {
        perror("msgget");
        return (void*)0;
    }

    memset(g_fileDataArr,0,sizeof(CDataFile *)*MAX_BOARD_NUM);
    printf("start threadDataSample\n");
    while(!g_exitFlag)
    {        
        
        int ret = msgrcv( msg_id, &msgSampleData, sizeof(sample_msg) ,QUEUE_MSG_TYPE_SAMPLE,IPC_NOWAIT );

        if(ret>0)
        {
            printf("recved msg of type QUEUE_MSG_TYPE_SAMPLE in threadDataSample\n");
            int boardId = msgSampleData.sampleMsg.boardId;
            switch(msgSampleData.sampleMsg.data_type)
            {
                case CAPACITY_SAMPLE:
                {
                    if(    g_fileCapData==NULL 
                        && msgSampleData.sampleMsg.act_type==START_SAMPLE)
                    {
                        g_fileCapData = new CDataFile("/mnt/nandflash/apps/cap_data.txt",boardId,msgSampleData.sampleMsg.chan,1024);
                        if(g_fileCapData)
                        {
                            can_frame canFrame;
                            encap_cap_gram(CENTRE_START,msgSampleData.sampleMsg.chan,CAP_SAMPLE,NULL,&canFrame);
                            
                            if(g_subBoardCanHandle)
                            {
                                printf("write can1, sid:%x\n",canFrame.can_id);
                                g_subBoardCanHandle->WriteCanPort(&canFrame);
                            }
                            
                        }
                        
                    }
                    else if(g_fileCapData!=NULL 
                        && msgSampleData.sampleMsg.act_type==STOP_SAMPLE) 
                    {
                        delete g_fileCapData;
                        g_fileCapData = NULL;

                        can_frame canFrame;
                        encap_cap_gram(CENTRE_STOP,msgSampleData.sampleMsg.chan,CAP_SAMPLE,NULL,&canFrame);

                        g_subBoardCanHandle->WriteCanPort(&canFrame);
                    }                   
                }
                break;
                case TEMPRATURE_SAMPLE:
                {
                    if(    g_fileDataArr[boardId-1]==NULL 
                        && msgSampleData.sampleMsg.act_type==START_SAMPLE)
                    {
                        
                        char fileName[64];
                        if(PURIFICATION_BOARD==boardId)
                        {
                            sprintf(fileName,"%s_%s.txt","temp_data","purify");
                        }
                        else if(THERMAL_SEAL_BOARD == boardId)
                        {
                            sprintf(fileName,"%s_%s.txt","temp_data","thermal");
                        }
                        else if(SYSTEM_CTRL_BOARD == boardId)
                        {
                            sprintf(fileName,"%s_%s.txt","temp_data","system");
                        }
                        
                        g_fileDataArr[boardId-1] = new CDataFile(fileName,msgSampleData.sampleMsg.chan,1024);
                        if(g_fileDataArr[boardId-1]!=NULL)
                        {
                            can_frame canFrame;
                            encap_temperature_gram(CENTRE_START,msgSampleData.sampleMsg.chan,&canFrame);
                            canFrame.can_id = 0x300 | boardId;
                            if(g_subBoardCanHandle)
                            {
                                g_subBoardCanHandle->WriteCanPort(&canFrame);
                            }
                            
                        }
                        
                    }
                    else if(g_fileDataArr[boardId-1]!=NULL 
                        && msgSampleData.sampleMsg.act_type==STOP_SAMPLE) 
                    {
                        delete g_fileDataArr[boardId-1];
                        g_fileDataArr[boardId-1] = NULL;

                        can_frame canFrame;
                        encap_temperature_gram(CENTRE_STOP,msgSampleData.sampleMsg.chan,&canFrame);
                        canFrame.can_id = 0x300 | (boardId&0x0f);

                        g_subBoardCanHandle->WriteCanPort(&canFrame);
                    }        
                }
                break;
                default:
                break;
            }
        }

    }
    return (void*)0;
}

int CDataFile::isValid(int fileIndex)
{
    if(dataFiles == NULL || fileIndex==-1)
    {
        return 0;
    }
    if(maxChanNum<=0 || fileChanNum==NULL)
    {
        return 0;
    }

    if(dataFiles[fileIndex].m_fd&&dataFiles[fileIndex].m_buff)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int CDataFile::getFileIndex(int chan)
{
    if(fileChanNum!=NULL && maxChanNum > 0)
    {
        return fileChanNum[chan];
    }
    else
    {
        return -1;
    }
    
}

void startSampleThread(void)
{
    pthread_t sampleThreadH;
    pthread_create(&sampleThreadH,NULL,threadDataSample,NULL);
}

void encap_temperature_gram(unsigned char op_code,unsigned char chanNum, void * dataOut )
{
    can_frame * framOut = (can_frame *)dataOut;
    memset(framOut,0,sizeof(can_frame));
    int count = 0;

    framOut->can_id = 0;
    framOut->data[0] = op_code;
    framOut->data[1] = chanNum;
    framOut->data[2] = CENTRE_SAMPLE_TEMPERATURE;
    framOut->can_dlc = 3;
    switch(framOut->data[2])
    {
        case CENTRE_SAMPLE_TEMPERATURE:
        break;
        default:
        break;
    }
}


